package com.sky.service.impl;

import com.alibaba.druid.util.StringUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.dto.SetmealDTO;
import com.sky.dto.SetmealPageQueryDTO;
import com.sky.entity.Setmeal;
import com.sky.entity.SetmealDish;
import com.sky.exception.DeletionNotAllowedException;
import com.sky.exception.SetmealEnableFailedException;
import com.sky.mapper.DishMapper;
import com.sky.mapper.SetmealDishMapper;
import com.sky.mapper.SetmealMapper;
import com.sky.result.PageResult;
import com.sky.service.SetmealService;
import com.sky.vo.DishItemVO;
import com.sky.vo.SetmealVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Service
public class SetmealServiceImpl implements SetmealService {

    @Autowired
    private SetmealMapper setmealMapper;

    @Autowired
    private SetmealDishMapper setmealDishMapper;

    @Autowired
    private DishMapper dishMapper;

    @Transactional
    @Override
    public void save(SetmealDTO setmealDTO) {
        // 1. 拷贝属性
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(setmealDTO, setmeal);
        setmeal.setStatus(StatusConstant.DISABLE);      // 默认禁用，需手动修改

        // 2.添加套餐基本数据（表 setmeal）
        setmealMapper.insert(setmeal);

        // 3.获取 insert 语句生成的主键值（套餐 id）
        Long setmealId = setmeal.getId();

        // 4.给套餐中的每个菜品赋上套餐 id
        List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
        setmealDishes.forEach(setmealDish -> setmealDish.setSetmealId(setmealId));

        // 5.添加套餐菜品数据（表 setmeal_dish）
        setmealDishMapper.insertBatch(setmealDishes);
    }

    @Override
    public PageResult pageQuery(SetmealPageQueryDTO pageQueryDTO) {
        // 1.设置分页参数
        PageHelper.startPage(pageQueryDTO.getPage(), pageQueryDTO.getPageSize());

        // 2.调用 mapper 查询数据
        List<SetmealVO> setmealVOList = setmealMapper.pageQuery(pageQueryDTO);

        // 3. 解析结果
        Page<SetmealVO> page = (Page<SetmealVO>) setmealVOList;
        return new PageResult(page.getTotal(), page.getResult());
    }

    @Override
    public SetmealVO getInfoById(Long id) {
        // 1.查询套餐基本信息(表 setmeal)
        Setmeal setmeal = setmealMapper.getById(id);

        // 2.查询套餐菜品信息(表 setmeal_dish)
        List<SetmealDish> setmealDishList = setmealDishMapper.getBySid(id);

        // 3.封装数据
        SetmealVO setmealVO = new SetmealVO();
        BeanUtils.copyProperties(setmeal, setmealVO);
        if (setmealDishList != null) {
            setmealVO.setSetmealDishes(setmealDishList);
        }

        // 4.返回结果
        return setmealVO;
    }

    @Override
    public void editInfo(SetmealDTO setmealDTO) {
        // 1.拷贝属性
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(setmealDTO, setmeal);

        // 2.更新套餐基本信息
        setmealMapper.update(setmeal);

        // 3.更新套餐菜品信息（先删、后插）
        // 3.1 删除原有菜品
        setmealDishMapper.deleteBySids(Collections.singletonList(setmeal.getId()));
        // 3.2 给新菜品赋上套餐 id
        List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
        if (!CollectionUtils.isEmpty(setmealDishes)) {  // 套餐菜品不为空
            setmealDishes.forEach(setmealDish -> {
                setmealDish.setSetmealId(setmeal.getId());
            });
        }
        // 3.3 更新
        setmealDishMapper.insertBatch(setmealDishes);
    }

    @Transactional
    @Override
    public void deleteBatch(List<Long> ids) {
        // 1.查询是否存在启售状态下的套餐
        Integer count = setmealMapper.countSellByIds(ids);
        if (count > 0) {
            throw new DeletionNotAllowedException(MessageConstant.SETMEAL_ON_SALE);
        }
        // 2.执行批量删除操作（删除 setmeal 表中的数据）
        setmealMapper.deleteBatch(ids);

        // 3.删除套餐菜品表(setmeal_dish)中的数据
        setmealDishMapper.deleteBySids(ids);
    }

    @Override
    public void enableOrDisable(Integer status, Long id) {
        // 1.构造实体
        Setmeal setmeal = Setmeal.builder()
                .id(id)
                .status(status)
                .build();

        // 优化了一下，停售操作则直接执行完后退出。减少访问数据库频率，提高效率

        // 2.停售操作
        if (status == StatusConstant.DISABLE) {
            setmealMapper.update(setmeal);
            return;
        }

        // 3.获取套餐内的菜品id列表
        List<Long> dishIds = setmealDishMapper.getDishIdsBySid(id);

        // 4.获取启售菜品数量
        Integer enableNum = dishMapper.countLaunchByIds(dishIds);

        // 5.判断菜品中是否有停售菜品
        if (enableNum != dishIds.size()) {    // 启售操作且有停售菜品
            throw new SetmealEnableFailedException(MessageConstant.SETMEAL_ENABLE_FAILED);
        }

        // 6.更新销售状态
        setmealMapper.update(setmeal);
    }

    @Override
    public List<Setmeal> listByCategoryId(Setmeal setmeal) {
        List<Setmeal> setmealList = setmealMapper.list(setmeal);
        return setmealList;
    }

    @Override
    public List<DishItemVO> getDishItemsById(Long sid) {
        List<DishItemVO> dishItemVOS = setmealMapper.getDishItemsById(sid);
        return dishItemVOS;
    }


}
